import { Tool, ToolColor } from '../../../Tool';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import * as turf from '@turf/turf';

/**
 * 距离测量
 */
export class DistanceTool extends Tool {
	constructor(viewer, options = {}, ...args) {
		super(arguments);
		this.viewer = viewer;
		this.lineData = [];
		this.moveData = [];
		this.startDraw = false;
		this.popupList = [];
		this.lastPopup = null;
	}

	//启动绘制事件
	start() {
		this.initMeasure();
		this.viewer.on('click', this.addLine);
		this.viewer.on('mousemove', this.addMoveLine);
		this.viewer.on('contextmenu', this.stopAdd);
	}

	initMeasure() {
		this.popupList.forEach((item) => {
			item.remove();
		});
		this.lastPopup && this.lastPopup.remove();
		this.lineData = [
			{
				type: 'Feature',
				geometry: {
					type: 'MultiLineString',
					coordinates: [[]]
				}
			}
		];
		this.viewer.getCanvas().style.cursor = 'crosshair';
		!this.viewer.getSource('distance') &&
			this.viewer.addSource('distance', {
				type: 'geojson',
				data: {
					type: 'FeatureCollection',
					features: []
				}
			});
		!this.viewer.getLayer('distance') &&
			this.viewer.addLayer({
				id: 'distance',
				source: 'distance',
				type: 'line',
				paint: {
					// 绘制类属性
					'line-opacity': 1, // 线的不透明度（可选，取值范围为 0 ~ 1，默认值为 1）
					'line-color': '#06CEAE', // 线的颜色（可选，默认值为 #000000。如果设置了 line-pattern，则 line-color 将无效）
					'line-width': 2 // 线的宽度（可选，值 >= 0，默认值为 1，单位：像素）
				}
			});
		!this.viewer.getLayer('distance_cap') &&
			this.viewer.addLayer({
				id: 'distance_cap',
				source: 'distance',
				type: 'circle',
				paint: {
					// 绘制类属性
					'circle-opacity': 1, // 圆点的不透明度（可选，取值范围为 0 ~ 1，默认值为 1）
					'circle-radius': 6, // 圆点的半径（可选，值 >= 0，默认值为 5，单位：像素）
					'circle-color': '#FFFF00' // 圆点的颜色（可选，默认值为 #000000）
				}
			});
	}

	addLine = (e) => {
		this.startDraw = true;
		this.lineData[0].geometry.coordinates[0].push([e.lngLat.lng, e.lngLat.lat]);
		let arr = this.lineData[0].geometry.coordinates[0];
		if (arr.length > 1) {
			let distance = this.getDistance([arr[arr.length - 1], arr[arr.length - 2]]);
			this.popupList.push(
				new mapboxgl.Popup({
					offset: {
						top: [0, 22]
					},
					closeButton: false, //如果为 true ，弹窗右上角将出现关闭按钮。
					closeOnClick: false, //如果为 true ，点击地图时弹窗将关闭。
					className: 'my-class'
				})
					.setLngLat(e.lngLat)
					.setHTML(
						`
            <div>
              <div><span>长度：</span><span>${distance}</span></div>
            </div>
          `
					)
					.setMaxWidth('300px')
					.addTo(this.viewer)
			);
		}
		let geojson = {
			type: 'FeatureCollection',
			features: this.lineData
		};
		this.viewer.getSource('distance').setData(geojson);
	};

	addMoveLine = (e) => {
		if (!this.startDraw) return;
		this.moveData = [
			{
				type: 'Feature',
				geometry: {
					type: 'MultiLineString',
					coordinates: [[]]
				}
			}
		];
		this.moveData[0].geometry.coordinates[0] = [
			...this.lineData[0].geometry.coordinates[0],
			[e.lngLat.lng, e.lngLat.lat]
		];
		let geojson = {
			type: 'FeatureCollection',
			features: this.moveData
		};
		this.viewer.getSource('distance').setData(geojson);

		this.lastPopup && this.lastPopup.remove();
		let distance = this.getDistance(this.moveData[0].geometry.coordinates[0]);
		this.lastPopup = new mapboxgl.Popup({
			offset: {
				top: [0, 22]
			},
			closeButton: false, //如果为 true ，弹窗右上角将出现关闭按钮。
			closeOnClick: false, //如果为 true ，点击地图时弹窗将关闭。
			className: 'my-class'
		})
			.setLngLat(e.lngLat)
			.setHTML(
				`
        <div>
          <div><span>总长度：</span><span>${distance}</span></div>
        </div>
      `
			)
			.setMaxWidth('300px')
			.addTo(this.viewer);
	};

	getDistance(lineList) {
		let line = turf.lineString(lineList);
		let length = turf.length(line, { units: 'kilometers' });
		if (length < 1) {
			return `${(length * 1000).toFixed(1)}M`;
		} else {
			return `${length.toFixed(2)}KM`;
		}
	}

	stopAdd = () => {
		if (!this.startDraw) return;
		this.clearListener();
		if (this.moveData[0].geometry.coordinates[0].length - 1 == this.popupList.length) {
			this.popupList[this.popupList.length - 1].remove();
		}
	};

	clearListener() {
		this.startDraw = false;
		this.viewer.getCanvas().style.cursor = '';
		this.viewer.off('click', this.addLine);
		this.viewer.off('mousemove', this.addLastPoint);
		this.viewer.off('contextmenu', this.stopAdd);
	}

	//停止绘制事件
	cancel() {
		this.clearListener();
		this.popupList.forEach((item) => {
			item.remove();
		});
		this.lastPopup && this.lastPopup.remove();

		this.viewer.getLayer('distance') && this.viewer.removeLayer('distance');
		this.viewer.getLayer('distance_cap') && this.viewer.removeLayer('distance_cap');

		this.viewer.getSource('distance') && this.viewer.removeSource('distance');
	}
}

DistanceTool.toolId = 'DistanceTool';
